Android Data Binding 이 library module 에서 오류 및 해결 방법 을 만 났 습 니 다.
Data Binding 을 사용 한 지 반년 이 넘 었 습 니 다.최초의 setVariable 에서 findViewById 를 교체 하고 비교적 고 급 스 러 운 양 방향 연결 까지 Adapter,Component 를 사용자 정의 하고 소스 코드 를 보고 컴 파일,운영 절 차 를 이해 하 는 것 도 작은 성과 라 고 할 수 있 습 니 다.또한 Data Binding 자체 의 실현 에 문제 가 발생 하지 않 았 습 니 다.
그러나 최근 재 구성 요소 화(MDCC 상 풍 숲 의'초심 으로 돌아 가 용기 화 에서 구성 요소 화 까지'참조)과정 에서 비교적 심각 한 BUG 를 만 났 다.AOSP 에 issue(\#224048)를 제출 했 습 니 다.바 꾸 는 것 은 번 거 롭 지 않 지만 gradle plugin 이기 때문에-"구 글 이 직접 하도록 하 세 요."하루빨리 복구 되 기 를 바 랍 니 다.
라 이브 러 리 모듈 생 성 클래스
library module 에서 Data Binding 을 사용 하 는 것 은 간단 합 니 다.application module 과 마찬가지 로:
android {
dataBinding {
enabled = true
}
}
생 성 된 binding 류 는 manifest 에서 지정 한 package name 의 databinding 패키지 에 있 습 니 다.구덩이.
그래서 구덩이 가 여기 있 었 습 니 다.번역 할 수 없 었 습 니 다.
왜?symbol 을 찾 을 수 없다 고 잘못 알 렸 습 니 다.그래서 module build 에서 생 성 된 Binding 류 를 보 았 습 니 다.왜 abstract 야?왜 그런 get 방법 을 못 찾 지?나 도 왜 우리 가 binding 류 에서 전에 set 에 들 어간 ViewModel 을 가 져 갔 는 지 모 르 겠 지만
WTF?!
What happened
Fuck 는 fuck,도대체 어떻게 된 일 인지 연구 해 야 한다.
저희 가 자세 가 틀 렸 나 요?Dagger 2 생 성 뭐 가 문제 야?아니면 Data Binding bug 인가요?
이전에 도 data binding 생 성 부분의 코드 를 연구 한 적 이 있 기 때문에 문제점 을 찾 는 데 시간 이 많이 걸 리 지 않 았 습 니 다.여 기 는 잔소리 가 많 지 않 고 해당 위 치 를 직접 봅 니 다.
Compiler Chief 의 writeView Binder Interfaces 에서:
public void writeViewBinderInterfaces(boolean isLibrary) {
ensureDataBinder();
mDataBinder.writerBaseClasses(isLibrary);
}
대응 하 는 DataBinder:
public void writerBaseClasses(boolean isLibrary) {
for (LayoutBinder layoutBinder : mLayoutBinders) {
try {
Scope.enter(layoutBinder);
if (isLibrary || layoutBinder.hasVariations()) {
String className = layoutBinder.getClassName();
String canonicalName = layoutBinder.getPackage() + "." + className;
if (mWrittenClasses.contains(canonicalName)) {
continue;
}
L.d("writing data binder base %s", canonicalName);
mFileWriter.writeToFile(canonicalName,
layoutBinder.writeViewBinderBaseClass(isLibrary));
mWrittenClasses.add(canonicalName);
}
} catch (ScopedException ex){
Scope.defer(ex);
} finally {
Scope.exit();
}
}
}
LayoutBinder 를 호출 했 습 니 다.(실제 구현 클래스 는 writeView Binder 를 호출 합 니 다.)
public String writeViewBinderBaseClass(boolean forLibrary) {
ensureWriter();
return mWriter.writeBaseClass(forLibrary);
}
library module 이 라면 우 리 는 특별한 컴 파일 을 할 것 이 며 진정한 실현 을 만 들 지 않 을 것 입 니 다.
public fun writeBaseClass(forLibrary : Boolean) : String =
kcode("package ${layoutBinder.`package`};") {
Scope.reset()
nl("import android.databinding.Bindable;")
nl("import android.databinding.DataBindingUtil;")
nl("import android.databinding.ViewDataBinding;")
nl("public abstract class $baseClassName extends ViewDataBinding {")
layoutBinder.sortedTargets.filter{it.id != null}.forEach {
tab("public final ${it.interfaceClass} ${it.fieldName};")
}
nl("")
tab("protected $baseClassName(android.databinding.DataBindingComponent bindingComponent, android.view.View root_, int localFieldCount") {
layoutBinder.sortedTargets.filter{it.id != null}.forEach {
tab(", ${it.interfaceClass} ${it.constructorParamName}")
}
}
tab(") {") {
tab("super(bindingComponent, root_, localFieldCount);")
layoutBinder.sortedTargets.filter{it.id != null}.forEach {
tab("this.${it.fieldName} = ${it.constructorParamName};")
}
}
tab("}")
nl("")
variables.forEach {
if (it.userDefinedType != null) {
val type = ModelAnalyzer.getInstance().applyImports(it.userDefinedType, model.imports)
tab("public abstract void ${it.setterName}($type ${it.readableName});")
}
}
tab("public static $baseClassName inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot) {") {
tab("return inflate(inflater, root, attachToRoot, android.databinding.DataBindingUtil.getDefaultComponent());")
}
tab("}")
tab("public static $baseClassName inflate(android.view.LayoutInflater inflater) {") {
tab("return inflate(inflater, android.databinding.DataBindingUtil.getDefaultComponent());")
}
tab("}")
tab("public static $baseClassName bind(android.view.View view) {") {
if (forLibrary) {
tab("return null;")
} else {
tab("return bind(view, android.databinding.DataBindingUtil.getDefaultComponent());")
}
}
tab("}")
tab("public static $baseClassName inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot, android.databinding.DataBindingComponent bindingComponent) {") {
if (forLibrary) {
tab("return null;")
} else {
tab("return DataBindingUtil.<$baseClassName>inflate(inflater, ${layoutBinder.modulePackage}.R.layout.${layoutBinder.layoutname}, root, attachToRoot, bindingComponent);")
}
}
tab("}")
tab("public static $baseClassName inflate(android.view.LayoutInflater inflater, android.databinding.DataBindingComponent bindingComponent) {") {
if (forLibrary) {
tab("return null;")
} else {
tab("return DataBindingUtil.<$baseClassName>inflate(inflater, ${layoutBinder.modulePackage}.R.layout.${layoutBinder.layoutname}, null, false, bindingComponent);")
}
}
tab("}")
tab("public static $baseClassName bind(android.view.View view, android.databinding.DataBindingComponent bindingComponent) {") {
if (forLibrary) {
tab("return null;")
} else {
tab("return ($baseClassName)bind(bindingComponent, view, ${layoutBinder.modulePackage}.R.layout.${layoutBinder.layoutname});")
}
}
tab("}")
nl("}")
}.generate()
}
그럼 문제 가 생 겼 습 니 다.여기 있 는 이것 은 library module 를 통 해 컴 파일 할 수 있 는 abstract class 일 뿐 입 니 다.모든 variable 의 setter 방법 만 생 성 되 었 습 니 다.getter 는 요?아버 지 는?구 글 이 이것 이 더 필요 하 다 는 것 을 전혀 고려 하지 않 은 것 같다.Kotlin 쓰 는 거 다 줄 어 들 었 어 요?
회피 안
library module 이 컴 파일 을 통과 할 수 있 도록(그래 야 applicationmodule 에서 진정한 Binding 을 생 성 할 수 있 습 니 다)getter 방법 을 사용 하 는 것 을 피 할 수 밖 에 없 었 습 니 다.다행히 이전에 개 발 된 DataBinding Adapter 와 lambda presenter 를 통 해 getter 를 사용 하여 view model 을 가 져 오 는 것 을 피 할 수 있 었 습 니 다.
어쨌든 구 글 이 다음 버 전에 서 이 문 제 를 복구 할 수 있 기 를 바 랍 니 다.iterator 입 니 다.abstract 인 터 페 이 스 를 쓸 뿐 입 니 다.
읽 어 주 셔 서 감사합니다. 여러분 에 게 도움 이 되 기 를 바 랍 니 다.본 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.